use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::env;
use tokio::time::{timeout, Duration};

#[derive(Debug, Serialize)]
struct DeepSeekRequest {
    model: String,
    messages: Vec<DeepSeekMessage>,
    max_tokens: Option<u32>,
    temperature: Option<f32>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
struct DeepSeekMessage {
    role: String,
    content: String,
}

#[derive(Debug, Deserialize)]
struct DeepSeekResponse {
    choices: Vec<DeepSeekChoice>,
}

#[derive(Debug, Deserialize)]
struct DeepSeekChoice {
    message: DeepSeekMessage,
}

#[derive(Clone)]
pub struct AIAgent {
    client: reqwest::Client,
    api_key: String,
    model_name: String,
}

impl AIAgent {
    pub async fn new() -> Result<Self> {
        // 检查 API 密钥
        let api_key = env::var("DEEPSEEK_API_KEY")
            .map_err(|_| anyhow::anyhow!("DEEPSEEK_API_KEY environment variable is not set"))?;

        if api_key.is_empty() {
            return Err(anyhow::anyhow!("DEEPSEEK_API_KEY is empty"));
        }

        println!("🤖 Initializing DeepSeek client via rig-core pattern...");

        let agent = Self {
            client: reqwest::Client::new(),
            api_key,
            model_name: "deepseek-chat".to_string(),
        };

        // 测试连接
        match timeout(Duration::from_secs(15), async {
            agent.test_connection().await
        }).await {
            Ok(Ok(_)) => {
                println!("✅ Successfully connected to DeepSeek");
                Ok(agent)
            }
            Ok(Err(e)) => {
                println!("❌ Failed to connect to DeepSeek: {}", e);
                println!("💡 Please check your DEEPSEEK_API_KEY and internet connection");
                Err(e)
            }
            Err(_) => {
                println!("⏰ Connection to DeepSeek timed out");
                Err(anyhow::anyhow!("Connection timeout"))
            }
        }
    }

    async fn test_connection(&self) -> Result<()> {
        let messages = vec![DeepSeekMessage {
            role: "user".to_string(),
            content: "Say 'Hello' if you're working correctly.".to_string(),
        }];

        self.send_completion(&messages).await?;
        Ok(())
    }

    async fn send_completion(&self, messages: &[DeepSeekMessage]) -> Result<String> {
        let request = DeepSeekRequest {
            model: self.model_name.clone(),
            messages: messages.to_vec(),
            max_tokens: Some(300),
            temperature: Some(0.7),
        };

        let response = self.client
            .post("https://api.deepseek.com/v1/chat/completions")
            .header("Authorization", format!("Bearer {}", self.api_key))
            .header("Content-Type", "application/json")
            .json(&request)
            .send()
            .await?;

        if response.status().is_success() {
            let deepseek_response: DeepSeekResponse = response.json().await?;
            if let Some(choice) = deepseek_response.choices.first() {
                Ok(choice.message.content.trim().to_string())
            } else {
                Err(anyhow::anyhow!("No response choices available"))
            }
        } else {
            let status = response.status();
            let text = response.text().await.unwrap_or_default();
            Err(anyhow::anyhow!("API request failed: {} - {}", status, text))
        }
    }

    pub async fn process_question(&self, question: &str, username: &str) -> Result<String> {
        let messages = vec![
            DeepSeekMessage {
                role: "system".to_string(),
                content: "You are a helpful AI assistant in a chat room. Provide concise, friendly, and helpful responses. Keep responses under 200 words.".to_string(),
            },
            DeepSeekMessage {
                role: "user".to_string(),
                content: format!("User '{}' asks: {}", username, question),
            },
        ];

        match timeout(Duration::from_secs(30), async {
            self.send_completion(&messages).await
        }).await {
            Ok(Ok(response)) => Ok(response),
            Ok(Err(e)) => {
                println!("❌ DeepSeek completion error: {}", e);
                Ok(format!("Sorry {}, I'm having trouble processing your question right now. Error: {}", username, e))
            }
            Err(_) => {
                println!("⏰ DeepSeek response timed out");
                Ok(format!("Sorry {}, your question is taking too long to process. Please try a simpler question.", username))
            }
        }
    }

    pub fn is_ai_mention(text: &str) -> bool {
        // 检查消息是否包含 @ai 提及
        let words: Vec<&str> = text.split_whitespace().collect();
        words.iter().any(|word| {
            word.eq_ignore_ascii_case("@ai")
                || word.starts_with("@ai,")
                || word.starts_with("@ai.")
                || word.starts_with("@ai!")
                || word.starts_with("@ai?")
        })
    }

    pub fn extract_question(text: &str) -> String {
        // 从消息中提取问题部分，去除 @ai
        let cleaned = text
            .split_whitespace()
            .filter(|word| {
                !word.eq_ignore_ascii_case("@ai")
                    && !word.starts_with("@ai,")
                    && !word.starts_with("@ai.")
                    && !word.starts_with("@ai!")
                    && !word.starts_with("@ai?")
            })
            .collect::<Vec<_>>()
            .join(" ");

        // 如果没有问题内容，返回默认提示
        if cleaned.trim().is_empty() {
            "Hello! How can I help you?".to_string()
        } else {
            cleaned.trim().to_string()
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_ai_mention() {
        assert!(AIAgent::is_ai_mention("@ai hello"));
        assert!(AIAgent::is_ai_mention("Hello @ai how are you?"));
        assert!(AIAgent::is_ai_mention("@ai, what time is it?"));
        assert!(AIAgent::is_ai_mention("@ai! help me"));
        assert!(AIAgent::is_ai_mention("@ai? are you there"));
        assert!(AIAgent::is_ai_mention("@AI hello")); // case insensitive

        assert!(!AIAgent::is_ai_mention("@alice hello"));
        assert!(!AIAgent::is_ai_mention("hello world"));
        assert!(!AIAgent::is_ai_mention("@airpods"));
    }

    #[test]
    fn test_extract_question() {
        assert_eq!(AIAgent::extract_question("@ai hello"), "hello");
        assert_eq!(
            AIAgent::extract_question("@ai, what time is it?"),
            "what time is it?"
        );
        assert_eq!(
            AIAgent::extract_question("Hello @ai how are you?"),
            "Hello how are you?"
        );
        assert_eq!(
            AIAgent::extract_question("@ai"),
            "Hello! How can I help you?"
        );
    }
}
